(function($) {
	var panels = function(els, options) {
		var pbody = $(els), self = this, opts = options, panel = null, headerBar = null, footerBar = null;
		$.extend(this, {
			init : init,
			getApi : function(e) {
				return panel;
			},
			setSite : function(options) {
				opts = $.extend( {}, opts, options);
				rSize();
			},
			getOpts : function() {
				return opts;
			},
			load : function(loadmethod, loadURL) {
				loadData(loadmethod, loadURL);
			},
			open : onOpen,
			close : onClose,
			toggle : onToggle
		});
		function init() {
			panel = pbody.addClass("panel-body").wrap(
					'<div class="panel"></div>').parent();
			rToolBar();
			rSize();
			loadData(opts.loadMethod, opts.loadURL);
		}
		// load data
		function loadData(loadmethod, loadURL) {
			if (opts.closable) {
				if (loadmethod != "") {
					switch (loadmethod) {
					case 'iframe': // May be able to streamline this if the
						// iframe
						// already exists.
						if (loadURL == '') {
							break;
						}
						pbody.html("");
						var iframe = $(
								'<iframe marginheight="0px" marginwidth="0px" height="100%" width="100%"  frameborder="0" scrolling="auto" src="' + loadURL + '"></iframe>')
								.prependTo(pbody);
						break;
					case 'html':
					default:
						// Need to test injecting elements as content.
						break;
					}
				}
			}
		}
		// Setting Toolbar
		function rToolBar() {
			// Setting HeaderToolbar
			opts.deltaHeight = 0;
			if (opts.title) {
				headerBar = $(
						"<div class=\"panel-header\"><div class=\"panel-title\">"
								+ opts.title + "</div></div>").prependTo(panel);
				headerBar.addClass(opts.headerCls);
				opts.deltaHeight = headerBar.outerHeight();
				var tools = $('<div class="panel-tools"></div>').appendTo(
						headerBar);
				if (opts.htools) {
					for ( var i = opts.htools.length - 1; i >= 0; i--) {
						var tool = $('<div></div>').addClass(
								opts.htools[i].iconCls).appendTo(tools);
						if (opts.htools[i].handler) {
							tool.bind('click', eval(opts.htools[i].handler));
						}
					}
				}
				if (opts.closable) {
					$('<div class="panel-tool-close"></div>').appendTo(tools)
							.bind('click', onClose);
				}
				if (opts.maximizable) {
					$('<div class="panel-tool-max"></div>').appendTo(tools)
							.bind('click', onMax);
				}
				if (opts.minimizable) {
					$('<div class="panel-tool-min"></div>').appendTo(tools)
							.bind('click', onMin);
				}
				if (opts.collapsible) {
					$('<div class="panel-tool-collapse"></div>')
							.appendTo(tools).bind('click', onToggle);
				}
				tools.find('div').hover(function() {
					$(this).addClass('panel-tool-over');
				}, function() {
					$(this).removeClass('panel-tool-over');
				});
			}
			// Setting FooterToolbar
			if (opts.footer) {
				footerBar = $("<div class=\"panel-footer\">&nbsp;</div>");
				pbody.addClass("panel-body-footer");
				panel.append(footerBar);
				opts.deltaHeight += footerBar.outerHeight();
				footerBar.addClass(opts.footerCls);
				var tools = $('<div class="panel-tools"></div>').appendTo(
						footerBar);
				if (opts.ftools) {
					for ( var i = opts.ftools.length - 1; i >= 0; i--) {
						var tool = $('<div></div>').addClass(
								opts.ftools[i].iconCls).appendTo(tools);
						if (opts.ftools[i].handler) {
							tool.bind('click', eval(opts.ftools[i].handler));
						}
					}
				}
			}
		}
		// Close panel
		function onClose() {
			if (!opts.closed) {
				closePanel();
			}
			return false;
		}
		function onOpen() {
			if (opts.closed) {
				openPanel();
			}
			return false;
		}
		function closePanel() {
			panel.hide();
			opts.closed = true;
			opts.onClose.call(panel);
		}
		function openPanel() {
			panel.show();
			opts.closed = false;
			opts.onOpen.call(panel);
		}

		function onMin() {
			if (!opts.closed) {
				minimizePanel();
			}
			return false;
		}
		function minimizePanel() {
			panel.hide();
			opts.closed = true;
			opts.onMinimize.call(panel);

		}
		function onMax() {
			if (opts.closable) {
				if (opts.maximized) {
					restorePanel();
				} else {
					maximizePanel();
				}
			}
			return false;
		}
		function maximizePanel() {
			headerBar.find('>.panel-tool-max').addClass('panel-tool-restore');
			var original = {
				width : opts.width,
				height : opts.height,
				left : opts.left,
				top : opts.top,
				fit : false
			};
			panel.data("restore", original);
			opts.left = 0;
			opts.top = 0;
			opts.fit = true;
			rSize();
			opts.minimized = false;
			opts.maximized = true;
			opts.onMaximize.call(panel);
		}
		function restorePanel() {
			headerBar.find('>.panel-tool-max')
					.removeClass('panel-tool-restore');
			var original = panel.data("restore");
			opts.width = original.width;
			opts.height = original.height;
			opts.left = original.left;
			opts.top = original.top;
			opts.fit = original.fit;
			rSize();
			opts.minimized = false;
			opts.maximized = false;
			opts.onRestore.call(panel);
		}
		function onToggle() {
			if (opts.closable) {
				if (opts.collapsed) {
					expandPanel();
				} else {
					collapsePanel();
				}
			}
			return false;
		}
		function collapsePanel() {
			headerBar.find('.panel-tool-collapse')
					.addClass('panel-tool-expand');
			footerBar.hide();
			pbody.slideUp('normal', function() {
				opts.collapsed = true;
				opts.onCollapse.call(panel);
				headerBar.css("border-bottom-width", "1px");
			});
		}
		// expandPanel
		function expandPanel() {
			headerBar.find('.panel-tool-collapse').removeClass(
					'panel-tool-expand');
			headerBar.css("border-bottom-width", "0px");
			pbody.slideDown('normal', function() {
				opts.collapsed = false;
				opts.onExpand.call(panel);
				footerBar.show();
			});
		}
		// Set pane Seze
		function rSize() {
			if (opts.fit == true) {
				var p = panel.parent();
				opts.width = p.width();
				opts.height = p.height();
			}
			panel.css(opts.style);
			panel.addClass(opts.cls);
			pbody.addClass(opts.bodyCls);
			panel.css( {
				left : opts.left,
				top : opts.top
			});
			if (!isNaN(opts.width)) {
				if ($.boxModel == true) {
					panel.width(opts.width
							- (panel.outerWidth() - panel.width()));
					pbody.width(panel.width()
							- (pbody.outerWidth() - pbody.width()));
				} else {
					panel.width(opts.width);
					pbody.width(panel.width());
				}
			} else {
				panel.width('auto');
				pbody.width('auto');
			}
			if (!isNaN(opts.height)) {
				if ($.boxModel == true) {
					panel.height(opts.height
							- (panel.outerHeight() - panel.height()));
					pbody.height(panel.height() - opts.deltaHeight
							- (pbody.outerHeight() - pbody.height()));
				} else {
					panel.height(opts.height);
					pbody.height(panel.height() - opts.deltaHeight);
				}
			} else {
				pbody.height('auto');
			}
			panel.css('height', null);
		}
	};
	$.fn.panel = function(options) {
		var pri = this.eq(typeof options == 'number' ? options : 0).data(
				"panel");
		if (pri) {
			return pri;
		}
		this.each(function() {
			var _opts = $.extend( {}, $.fn.panel.defaults, {
				width : (parseInt($(this).css("width")) || undefined),
				height : (parseInt($(this).css("height")) || undefined),
				top : (parseInt($(this).css("top")) || undefined),
				left : (parseInt($(this).css("left")) || undefined),
				title : $(this).attr("title")
			}, options);
			$(this).attr("title", "");
			var opts = $.meta ? $.extend( {}, _opts, this.data()) : _opts;
			pri = new panels(this, opts);
			pri.init();
			$(this).data("panel", pri);
		});
		return pri;
	};
	$.fn.panel.defaults = {
		api : true,
		title : null,
		loadMethod : null,// iframe
		loadURL : null,
		cls : null,
		headerCls : null,
		bodyCls : null,
		footerCls : null,
		style : {},
		width : "auto",
		height : "auto",
		left : null,
		top : null,
		footer : false,
		htools : [],
		ftools : [],
		closable : true,
		minimizable : false,
		maximizable : false,
		collapsible : false,
		onMinimize : function() {
		},
		onMaximize : function() {
		},
		onRestore : function() {
		},
		onClose : function() {
		},
		onOpen : function() {
		},
		onCollapse : function() {
		},
		onExpand : function() {
		}
	};
})(jQuery);
// http://dzh2.mop.com/topic/readNewbie_9943612_0_0.html
